package com.gitee.apanlh.util.net.http;

import com.gitee.apanlh.exp.HttpConfigException;
import com.gitee.apanlh.util.encode.CharsetCode;
import com.gitee.apanlh.util.log.LogLevel;
import com.gitee.apanlh.web.http.HttpMethod;

/**	
 * 	HTTP-客户端配置
 * 	
 * 	@author Pan
 */
public class HttpConfig {
	
	/** 传输字符编码 */
	private String charset;
	/** 请求方法 */
	private HttpMethod httpMethod;
	/** 连接超时时长(单位毫秒)*/
	private int connectTimeout;
	/** 读取超时时长(单位毫秒) */
 	private int readTimeout;
	/** 是否允许写出 */
	private boolean hasOutput;
	/** 是否允许读入 */
	private boolean hasInput;
	/** 写入请求体内容 */
	private boolean writeRequestLog = true;
	/** 写入返回体内容 */
	private boolean writeResponseLog = true;
	/** 是否开启RESTful */
	private boolean hasEnableRest;
	/** 是否开启参数urlEncode */
	private boolean hasParamUrlEncode = true;
	/** 记录日志等级 默认DEBUG */
	private LogLevel logLevel = LogLevel.DEBUG;
	/** 错误响应日志等级 默认INFO */
	private LogLevel errorLogLevel = LogLevel.INFO;
	
	/**
	 * 	默认构造函数
	 * 	
	 * 	@author Pan
	 */
	HttpConfig() {
		super();
	}
	
	/**
	 * 	构造函数
	 * 	<br>全局统一超时时长
	 * 	<br>自定义参数
	 * 	<br>默认UTF-8传输编码
	 * 	
	 * 	@author Pan
	 * 	@param 	httpMethod		请求方法
	 * 	@param 	globalTimeout	全局统一超时时长(单位毫秒)
	 * 	@param 	hasOutput		是否允许写出
	 * 	@param 	hasInput		是否允许读入
	 */
	HttpConfig(HttpMethod httpMethod, int globalTimeout, boolean hasOutput, boolean hasInput) {
		this(httpMethod, globalTimeout, globalTimeout, hasOutput, hasInput, CharsetCode.UTF_8);
	}
	
	/**
	 * 	构造函数
	 * 	<br>自定义参数
	 * 	
	 * 	@author Pan
	 * 	@param 	httpMethod		请求方法
	 * 	@param 	connectTimeout	连接超时时长(单位毫秒)
	 * 	@param 	readTimeout		读取超时时长(单位毫秒)
	 * 	@param 	hasOutput		是否允许写出
	 * 	@param 	hasInput		是否允许读入
	 * 	@param 	charset			传输字符编码集
	 */
	HttpConfig(HttpMethod httpMethod, int connectTimeout, int readTimeout, boolean hasOutput, boolean hasInput, String charset) {
		this.httpMethod = httpMethod;
		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
		this.hasOutput = hasOutput;
		this.hasInput = hasInput;
		this.charset = charset;
	}

    /**
     * 	获取-HTTP请求方法
     * 	
     * 	@author Pan
     * 	@return	HttpMethod
     */
    public HttpMethod getHttpMethod() {
		return httpMethod;
	}

	/**
	 * 	获取-连接超时参数(单位毫秒)
	 * 
	 * 	@author Pan
	 * 	@return	int
	 */
	public int getConnectTimeout() {
		return connectTimeout;
	}

	/**
	 * 	获取-读取超时参数(单位毫秒)
	 * 
	 * 	@author Pan
	 * 	@return	int
	 */
	public int getReadTimeout() {
		return readTimeout;
	}

	/**	
	 * 	获取-当前字符编码集
	 * 	
	 * 	@author Pan
	 * 	@return	String
	 */	
	public String getCharset() {
		return charset;
	}
	
	/**
	 * 	设置-HTTP请求方法
	 * 	
	 * 	@author Pan
	 * 	@param 	httpMethod	HTTP请求方法
	 * 	@return	HttpConfig
	 */
	public HttpConfig setHttpMethod(HttpMethod httpMethod) {
		this.httpMethod = httpMethod;
		return this;
	}

	/**	
	 * 	设置-允许写入状态
	 * 	
	 * 	@author Pan
	 * 	@param 	hasInput	是否允许写入
	 * 	@return	HttpConfig
	 */
	public HttpConfig setInput(boolean hasInput) {
		this.hasInput = hasInput;
		return this;
	}
	
	/**
	 * 	设置-允许写出状态
	 * 	
	 * 	@author Pan
	 * 	@param 	hasOutput	是否允许写出
	 * 	@return	HttpConfig
	 */
	public HttpConfig setOutput(boolean hasOutput) {
		this.hasOutput = hasOutput;
		return this;
	}
	
	/**
	 * 	设置-连接超时参数(单位毫秒)
	 * 	
	 * 	@author Pan
	 * 	@param 	connectTimeout	连接超时参数(单位毫秒)
	 * 	@return	HttpConfig
	 */
	public HttpConfig setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
		return this;
	}
	
	/**
	 * 	设置-读取超时参数(单位毫秒)
	 * 	
	 * 	@author Pan
	 * 	@param 	readTimeout	读取超时参数(单位毫秒)
	 * 	@return	HttpConfig
	 */
	public HttpConfig setReadTimeout(int readTimeout) {
		this.readTimeout = readTimeout;
		return this;
	}
	
	/**	
	 * 	设置-字符编码集
	 * 	
	 * 	@author Pan
	 * 	@param 	charset	字符编码集
	 * 	@return	HttpConfig
	 */
	public HttpConfig setCharset(String charset) {
		this.charset = charset;
		return this;
	}
	
	/**	
	 * 	设置-是否开启发送时打印请求体内容
	 * 	
	 * 	@author Pan
	 * 	@param 	writeRequestLog	true开启
	 */
	public void setWriteRequestLog(boolean writeRequestLog) {
		this.writeRequestLog = writeRequestLog;
	}
	
	/**	
	 * 	设置-是否开启返回时打印响应体内容
	 * 	
	 * 	@author Pan
	 * 	@param 	writeResponseLog true开启
	 */
	public void setWriteResponseLog(boolean writeResponseLog) {
		this.writeResponseLog = writeResponseLog;
	}
	
	/**	
	 * 	设置-开启RESTful
	 * 	
	 * 	@author Pan
	 * 	@param 	hasEnableRest	true开启
	 */
	public void setHasEnableRest(boolean hasEnableRest) {
		this.hasEnableRest = hasEnableRest;
	}


	/**
	 * 	设置-开启参数UrlEncode
	 *
	 * 	@author Pan
	 * 	@param 	hasEnable	true开启
	 */
	public void setHasParamUrlEncode(boolean hasEnable) {
		this.hasParamUrlEncode = hasEnable;
	}

	/**	
	 * 	设置日志等级
	 * 	
	 * 	@author Pan
	 * 	@param 	logLevel 日志等级
	 */
	public void setLogLevel(LogLevel logLevel) {
		this.logLevel = logLevel;
	}

	/**	
	 * 	设置-错误响应日志等级
	 * 	
	 * 	@author Pan	
	 * 	@param 	errorLogLevel	错误日志等级
	 */
	public void setErrorLogLevel(LogLevel errorLogLevel) {
		this.errorLogLevel = errorLogLevel;
	}

	/**	
	 * 	获取-日志等级
	 * 	
	 * 	@author Pan
	 * 	@return	LogLevel
	 */
	public LogLevel getLogLevel() {
		return logLevel;
	}
	
	/**	
	 * 	获取-错误响应日志等级
	 * 	
	 * 	@author Pan
	 * 	@return	LogLevel
	 */
	public LogLevel getErrorLogLevel() {
		return errorLogLevel;
	}
	
	/**	
	 * 	获取-是否开启RESTful
	 * 	
	 * 	@author Pan
	 * 	@return	boolean
	 */
	public boolean hasHasEnableRest() {
		return hasEnableRest;
	}

	/**
	 * 	获取-当前是否允许写出
	 * 	
	 * 	@author Pan
	 * 	@return	boolean
	 */
	public boolean hasHasOutput() {
		return hasOutput;
	}

	/**
	 * 	获取-当前是否允许写入
	 * 	
	 * 	@author Pan
	 * 	@return	boolean
	 */
	public boolean hasHasInput() {
		return hasInput;
	}
	
	/**	
	 * 	获取-是否开启发送时写入响应体内容
	 * 	
	 * 	@author Pan
	 * 	@return	boolean
	 */
	public boolean hasWriteRequestBody() {
		return writeRequestLog;
	}

	/**
	 * 	获取-是否开启返回时写入响应体内容
	 * 	
	 * 	@author Pan
	 * 	@return	boolean
	 */
	public boolean hasWriteResponseBody() {
		return writeResponseLog;
	}

	/**
	 * 	获取-是否开启请求发送时进行urlEncode
	 *
	 * 	@author Pan
	 * 	@return	boolean
	 */
	public boolean hasParamUrlEncode() {
		return hasParamUrlEncode;
	}

	/**
	 *  创建HTTP配置
	 *  
	 * 	@author Pan
	 * 	@return	HttpConfig
	 */
	public static HttpConfig create() {
		return new HttpConfig();
	}
	
	/**	
	 *  创建HTTP配置
	 *  <br>根据请求类型自动装配HTTP配置
	 *  
	 * 	@author Pan
	 * 	@param 	httpMethod			请求类型
	 * 	@return	HttpConfig
	 */
	protected static HttpConfig create(HttpMethod httpMethod) {
    	switch (httpMethod) {
			case GET:
				return createGet();
			case POST:
				return createPost();
			case DELETE:
				return createDelete();
			case PUT: 
				return createPut();
			default:
				throw new HttpConfigException("http config error, unknown http method type");
		}
	}
	
	/**	
	 * 	创建HTTP配置
	 * 	<br>全局统一超时时长
	 * 	<br>自定义参数
	 * 	
	 * 	@author Pan
	 * 	@param 	httpMethod		请求方法
	 * 	@param 	globalTimeout	全局统一超时时长(单位毫秒)
	 * 	@param 	hasOutput		是否允许写出
	 * 	@param 	hasInput		是否允许读入
	 * 	@return HttpConfig
	 */
	static HttpConfig create(HttpMethod httpMethod, int globalTimeout, boolean hasOutput, boolean hasInput) {
		return new HttpConfig(httpMethod, globalTimeout, hasOutput, hasInput);
	}

	/**	
	 * 	创建HTTP配置
	 * 	<br>自定义参数
	 * 
	 * 	@author Pan
	 * 	@param 	httpMethod		请求方法
	 * 	@param 	connectTimeout	连接超时时长(单位毫秒)
	 * 	@param 	readTimeout		读取超时时长(单位毫秒)
	 * 	@param 	hasOutput		是否允许写出
	 * 	@param 	hasInput		是否允许读入
	 * 	@param 	charset			字符编码集
	 * 	@return HttpConfig
	 */
	static HttpConfig create(HttpMethod httpMethod,  int connectTimeout, int readTimeout, boolean hasOutput, boolean hasInput, String charset) {
		return new HttpConfig(httpMethod, connectTimeout, readTimeout, hasOutput, hasInput, charset);
	}
	
	/**	
	 * 	创建GET请求默认配置
	 * 	<br>全局超时为60秒
	 * 	
	 * 	@author Pan
	 * 	@return	HttpConfig
	 */
	static HttpConfig createGet() {
		return createGet(60000);
	}
	
	/**	
	 * 	创建GET请求默认配置
	 * 	<br>自定义全局时长
	 * 	
	 * 	@author Pan
	 * 	@param 	globalTimeout		全局统一超时时长(单位毫秒)
	 * 	@return	HttpConfig
	 */	
	static HttpConfig createGet(int globalTimeout) {
		return create(HttpMethod.GET, globalTimeout, false, true);
	}
	
	/**	
	 * 	创建POST请求默认配置
	 * 	<br>全局超时为60秒
	 * 	
	 * 	@author Pan
	 * 	@return	HttpConfig
	 */
	static HttpConfig createPost() {
		return createPost(60000);
	}
	
	/**	
	 * 	创建POST请求默认配置
	 * 	<br>自定义全局时长
	 * 	
	 * 	@author Pan
	 * 	@param 	globalTimeout		全局统一超时时长(单位毫秒)
	 * 	@return	HttpConfig
	 */
	static HttpConfig createPost(int globalTimeout) {
		return create(HttpMethod.POST, globalTimeout, true, true);
	}
	
	/**	
	 * 	创建DELETE请求默认配置
	 * 	<br>全局超时为60秒
	 * 	
	 * 	@author Pan
	 * 	@return	HttpConfig
	 */
	static HttpConfig createDelete() {
		return createDelete(60000);
	}
	
	/**	
	 * 	创建DELETE请求默认配置
	 * 	<br>自定义全局时长
	 * 	
	 * 	@author Pan
	 * 	@param 	globalTimeout		全局统一超时时长(单位毫秒)
	 * 	@return	HttpConfig
	 */
	static HttpConfig createDelete(int globalTimeout) {
		return create(HttpMethod.DELETE, globalTimeout, true, true);
	}
	
	/**	
	 * 	创建PUT请求默认配置
	 * 	<br>全局超时为60秒
	 * 	
	 * 	@author Pan
	 * 	@return	HttpConfig
	 */
	static HttpConfig createPut() {
		return createPut(60000);
	}
	
	/**	
	 * 	创建PUT请求默认配置
	 * 	<br>自定义全局时长
	 * 	
	 * 	@author Pan
	 * 	@param 	globalTimeout		全局统一超时时长(单位毫秒)
	 * 	@return	HttpConfig
	 */
	static HttpConfig createPut(int globalTimeout) {
		return create(HttpMethod.PUT, globalTimeout, true, true);
	}
}
